package com.cosina.test;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.text.Format;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import static javax.microedition.khronos.opengles.GL10.*;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.util.Log;

public class Lession10Render implements Renderer,DirectionListener{
	float yrot;       /* Camera rotation variable */
	float xpos, zpos; /* Camera pos variable */
	float walkbias, walkbiasangle;
	float lookupdown = 0.0f;
	
	float[] materialAmb = {0.2f, 0.2f, 0.2f, 0.2f};
	float[] materialDif = {0.8f, 0.8f, 0.8f, 0.8f};
	
	static final float piover180 = 0.0174532925f;
	
	int texture;
	
	int one = 0x10000;
	Sector Sector = new Sector();
	
	public Lession10Render(){
		BufferedReader br = new BufferedReader(new InputStreamReader(DataManager.getFile("data/world.txt")));
	
		Triangle triangle = new Triangle();
		int vertexIndex = 0;
		try {
			String line = null;
			while((line = br.readLine()) != null){
				if(line.trim().length() <= 0 || line.startsWith("/")){
					continue;
				}
				
				Log.e("cosina1985", line);
				String part[] = line.trim().split("\\s+");
//				Log.e("cosina1985", "part[0]" + part[0]);
//				Log.e("cosina1985", "part[1]" + part[1]);
//				Log.e("cosina1985", "part[2]" + part[2]);
//				Log.e("cosina1985", "part[3]" + part[3]);
//				Log.e("cosina1985", "part[4]" + part[4]);
				float x = Float.valueOf(part[0]);
				float y = Float.valueOf(part[1]);
				float z = Float.valueOf(part[2]);
				float u = Float.valueOf(part[3]);
				float v = Float.valueOf(part[4]);
				Vertex vertex = new Vertex(x, y, z, u, v);
				triangle.vertexs[vertexIndex] = vertex;
				
				vertexIndex ++;
				if(vertexIndex == 3){
					vertexIndex = 0;
					Sector.triangles.add(triangle);
					triangle = new Triangle();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		loadTexture(gl);
		gl.glEnable(GL_TEXTURE_2D);
		gl.glShadeModel(GL10.GL_SMOOTH);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepthf(1.0f);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
		
		gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
		gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE);
		
		gl.glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materialAmb,0);
		gl.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materialDif,0);
	}
	
	private void loadTexture(GL10 gl) {
		IntBuffer textureBuffer = IntBuffer.allocate(3);
		gl.glGenTextures(1, textureBuffer);
		texture = textureBuffer.get();
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
		
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, DataManager.getBm(R.drawable.mud), 0);
		gl.glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		gl.glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		
		
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		
		float xtrans = -xpos;
		float ztrans = -zpos;
		float ytrans = -walkbias - 0.25f;
		float sceneroty = 360.0f - yrot;
		
		FloatBuffer vertexPointer = FloatBuffer.wrap(new float[9]);
		FloatBuffer texCoordPointer = FloatBuffer.wrap(new float[6]);
		gl.glVertexPointer(3, GL_FLOAT, 0, vertexPointer);
		gl.glTexCoordPointer(2, GL_FLOAT, 0, texCoordPointer);
		
		gl.glEnableClientState(GL_VERTEX_ARRAY);
	    gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	    
	    gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	    
	    gl.glLoadIdentity();
	    
	    gl.glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);
	    gl.glRotatef(sceneroty, 0.0f, 1.0f, 0.0f);
	    
	    gl.glTranslatef(xtrans, ytrans, ztrans);
	    
	    gl.glBindTexture(GL_TEXTURE_2D, texture);
	    
	    for(Triangle triangle : Sector.triangles){
	    	vertexPointer.clear();
	    	texCoordPointer.clear();
	    	gl.glNormal3f(0.0f, 0.0f, 1.0f);
	    	for(int i=0; i<3; i++){
	    		Vertex vt = triangle.vertexs[i];
	    		vertexPointer.put(vt.x);
	    		vertexPointer.put(vt.y);
	    		vertexPointer.put(vt.z);
	    		texCoordPointer.put(vt.u);
	    		texCoordPointer.put(vt.v);
	    	}
	    	gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 4);
	    }
	    
	    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}
	
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);

		float ratio = (float) width / height;
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	@Override
	public void doDown() {
		 xpos+=(float)Math.sin(yrot*piover180)*0.05f;
	        /* Move On The Z-Plane Based On Player Direction */
	        zpos+=(float)Math.cos(yrot*piover180)*0.05f;
	        if (walkbiasangle<=1.0f)
	        {
	           walkbiasangle=359.0f;
	        }
	        else
	        {
	           walkbiasangle-=10;
	        }
	        walkbias=(float)Math.sin(walkbiasangle*piover180)/20.0f;
		
	}

	@Override
	public void doLeft() {
		 yrot+=1.5f;
		
	}

	@Override
	public void doRight() {
		  yrot-=1.5f;
	}

	@Override
	public void doUp() {
		xpos -= (float)Math.sin(yrot*piover180)*0.05f;
		zpos -= (float)Math.cos(yrot*piover180)*0.05f;
		if(walkbiasangle >= 359.0f)
			walkbiasangle = 0.0f;
		else
			walkbiasangle +=10;
		
		 walkbias=(float)Math.sin(walkbiasangle*piover180)/20.0f;
	}
}

class Vertex{ float x,y,z, u,v;
	public Vertex(float x,float y,float z,float u,float v){
		this.x = x;
		this.y = y;
		this.z = z;
		this.u = u;
		this.v = v;
	}
}
class Triangle{Vertex[] vertexs = new Vertex[3];}
class Sector {List<Triangle> triangles = new ArrayList<Triangle>();}